package com.zis.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;

/**
 * 
 * <b>说明：</b>日期计算工具类
 * 
 * @ClassName: DateUtils
 * @author zhaohaitao(2543) 日期： 2015-7-24 上午11:45:24
 * 
 */
public class DateUtils
{
    private StringBuffer buffer = new StringBuffer();
    
    /**
     * 补位字符
     */
    private static String ZERO = "0";
    
    private static DateUtils date;
    
    public static final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
    
    public static final SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
    
    public static String formatDateTime(Date date)
    {
        if (DateFormat.getDateTimeInstance().format(date).contains("0:00:00"))
        {
            return DateFormat.getDateInstance().format(date);
        }
        return DateFormat.getDateTimeInstance().format(date);
    }
    
    /**
     * 根据用户指定的格式转换日期格式
     * 
     * @param date 需要转换的日期
     * @param pattern 转换格式
     * @return String 返回类型
     */
    public static String format(Date date, String pattern)
    {
        return DateFormatUtils.format(date, pattern, null, null);
    }
    
    /**
     * 将日期格式化为 yyyy-MM-dd HH:mm:ss
     * 
     * @param datetime
     * @return
     */
    public static Date parseDateTime(Date datetime)
    {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date result = datetime;
        try
        {
            result = format.parse(DateFormat.getDateInstance().format(datetime));
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
        return result;
    }
    
    /**
     * 将日期格式化为 HH:mm:ss
     * 
     * @param time
     * @return
     */
    public static Date parseTime(Date time)
    {
        DateFormat format = new SimpleDateFormat("HH:mm:ss");
        Date result = time;
        try
        {
            result = format.parse(DateFormat.getTimeInstance().format(time));
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
        return result;
    }
    
    /**
     * 将日期格式化为 yyyy-MM-dd
     * 
     * @param time
     * @return
     */
    public static Date parseDate(Date time)
    {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date result = time;
        try
        {
            result = format.parse(DateFormat.getDateInstance().format(time));
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
        return result;
    }
    
    /**
     * 根据制定的格式将字符串转换为日期格式
     * 
     * @param @param strDate 字符串日期
     * @param @param pattern 字符串日期格式
     * @return Date 返回类型
     */
    public static Date parse(String strDate, String pattern)
        throws ParseException
    {
        return StringUtils.isBlank(strDate) ? null : new SimpleDateFormat(pattern).parse(strDate);
    }
    
    /**
     * 获取当前日期的字符串格式:20150724115100
     * 
     * @return String 返回类型
     */
    public String getNowString()
    {
        Calendar calendar = getCalendar();
        buffer.delete(0, buffer.capacity());
        buffer.append(getYear(calendar));
        if (getMonth(calendar) < 10)
        {
            buffer.append(ZERO);
        }
        buffer.append(getMonth(calendar));
        
        if (getDate(calendar) < 10)
        {
            buffer.append(ZERO);
        }
        buffer.append(getDate(calendar));
        if (getHour(calendar) < 10)
        {
            buffer.append(ZERO);
        }
        buffer.append(getHour(calendar));
        if (getMinute(calendar) < 10)
        {
            buffer.append(ZERO);
        }
        buffer.append(getMinute(calendar));
        if (getSecond(calendar) < 10)
        {
            buffer.append(ZERO);
        }
        buffer.append(getSecond(calendar));
        return buffer.toString();
    }
    
    private static int getDateField(Date date, int field)
    {
        Calendar c = getCalendar();
        c.setTime(date);
        return c.get(field);
    }
    
    /**
     * 获取两个日期之间的年数
     * 
     * @param begin 开始日期
     * @param end 结束日期
     * @return int 返回类型
     */
    public static int getYearsBetweenDate(Date begin, Date end)
    {
        int bYear = getDateField(begin, Calendar.YEAR);
        int eYear = getDateField(end, Calendar.YEAR);
        return eYear - bYear;
    }
    
    /**
     * 获取两个日期之间的月数
     * 
     * @param begin 开始日期
     * @param end 结束日期
     * @return int 返回类型
     */
    public static int getMonthsBetweenDate(Date begin, Date end)
    {
        int bMonth = getDateField(begin, Calendar.MONTH);
        int eMonth = getDateField(end, Calendar.MONTH);
        return eMonth - bMonth;
    }
    
    /**
     * 获取两个日期之间的周数
     * 
     * @param begin 开始日期
     * @param end 结束日期
     * @return int 返回类型
     */
    public static int getWeeksBetweenDate(Date begin, Date end)
    {
        int bWeek = getDateField(begin, Calendar.WEEK_OF_YEAR);
        int eWeek = getDateField(end, Calendar.WEEK_OF_YEAR);
        return eWeek - bWeek;
    }
    
    /**
     * 计算两个日期之间的天数
     * 
     * @param begin 开始日期
     * @param end 结束日期
     * @return int 返回类型
     */
    public static int getDaysBetweenDate(Date begin, Date end)
    {
        return (int)((end.getTime() - begin.getTime()) / (1000 * 60 * 60 * 24));
    }
    
    public static void main(String args[])
    {
        // System.out.println(getSpecficDateStart(new Date(), 288));
        System.out.println(DateUtils.getDateInstance().getNowString());
    }
    
    /**
     * 获取date年后的amount年的第一天的开始时间
     * 
     * @param amount 可正、可负
     * @return
     */
    public static Date getSpecficYearStart(Date date, int amount)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, amount);
        cal.set(Calendar.DAY_OF_YEAR, 1);
        return getStartDate(cal.getTime());
    }
    
    /**
     * 获取date年后的amount年的最后一天的终止时间
     * 
     * @param amount 可正、可负
     * @return
     */
    public static Date getSpecficYearEnd(Date date, int amount)
    {
        Date temp = getStartDate(getSpecficYearStart(date, amount + 1));
        Calendar cal = Calendar.getInstance();
        cal.setTime(temp);
        cal.add(Calendar.DAY_OF_YEAR, -1);
        return getFinallyDate(cal.getTime());
    }
    
    /**
     * 获取date月后的amount月的第一天的开始时间
     * 
     * @param amount 可正、可负
     * @return
     */
    public static Date getSpecficMonthStart(Date date, int amount)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, amount);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        return getStartDate(cal.getTime());
    }
    
    /**
     * 获取当前自然月后的amount月的最后一天的终止时间
     * 
     * @param amount 可正、可负
     * @return
     */
    public static Date getSpecficMonthEnd(Date date, int amount)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getSpecficMonthStart(date, amount + 1));
        cal.add(Calendar.DAY_OF_YEAR, -1);
        return getFinallyDate(cal.getTime());
    }
    
    /**
     * 获取date周后的第amount周的开始时间（这里星期一为一周的开始）
     * 
     * @param amount 可正、可负
     * @return
     */
    public static Date getSpecficWeekStart(Date date, int amount)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.setFirstDayOfWeek(Calendar.MONDAY); /* 设置一周的第一天为星期一 */
        cal.add(Calendar.WEEK_OF_MONTH, amount);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return getStartDate(cal.getTime());
    }
    
    /**
     * 获取date周后的第amount周的最后时间（这里星期日为一周的最后一天）
     * 
     * @param amount 可正、可负
     * @return
     */
    public static Date getSpecficWeekEnd(Date date, int amount)
    {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY); /* 设置一周的第一天为星期一 */
        cal.add(Calendar.WEEK_OF_MONTH, amount);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return getFinallyDate(cal.getTime());
    }
    
    /**
     * 获取 date日期对应的amount天之后的日期
     * 
     * @param date
     * @param amount
     * @return
     */
    public static Date getSpecficDateStart(Date date, int amount)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_YEAR, amount);
        return getStartDate(cal.getTime());
    }
    
    /**
     * 得到指定日期的一天的的最后时刻23:59:59
     * 
     * @param date
     * @return
     */
    public static Date getFinallyDate(Date date)
    {
        String temp = format.format(date);
        temp += " 23:59:59";
        
        try
        {
            return format1.parse(temp);
        }
        catch (ParseException e)
        {
            return null;
        }
    }
    
    /**
     * 得到指定日期的一天的开始时刻00:00:00
     * 
     * @param date
     * @return
     */
    public static Date getStartDate(Date date)
    {
        String temp = format.format(date);
        temp += " 00:00:00";
        
        try
        {
            return format1.parse(temp);
        }
        catch (Exception e)
        {
            return null;
        }
    }
    
    /**
     * 
     * @param date 指定比较日期
     * @param compareDate
     * @return
     */
    public static boolean isInDate(Date date, Date compareDate)
    {
        if (compareDate.after(getStartDate(date)) && compareDate.before(getFinallyDate(date)))
        {
            return true;
        }
        else
        {
            return false;
        }
        
    }
    
    /**
     * 获取两个时间的差值秒
     * 
     * @param d1
     * @param d2
     * @return
     */
    public static Integer getSecondBetweenDate(Date d1, Date d2)
    {
        Long second = (d2.getTime() - d1.getTime()) / 1000;
        return second.intValue();
    }
    
    private int getYear(Calendar calendar)
    {
        return calendar.get(Calendar.YEAR);
    }
    
    private int getMonth(Calendar calendar)
    {
        return calendar.get(Calendar.MONDAY) + 1;
    }
    
    private int getDate(Calendar calendar)
    {
        return calendar.get(Calendar.DATE);
    }
    
    private int getHour(Calendar calendar)
    {
        return calendar.get(Calendar.HOUR_OF_DAY);
    }
    
    private int getMinute(Calendar calendar)
    {
        return calendar.get(Calendar.MINUTE);
    }
    
    private int getSecond(Calendar calendar)
    {
        return calendar.get(Calendar.SECOND);
    }
    
    private static Calendar getCalendar()
    {
        return Calendar.getInstance();
    }
    
    public static DateUtils getDateInstance()
    {
        if (date == null)
        {
            date = new DateUtils();
        }
        return date;
    }
}
